package org.hongqi.common.senpec.person.certification;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hongqi.common.senpec.base.mybatisplus.IBaseServiceImpl;
import org.hongqi.common.senpec.base.sevlet.Result;
import org.hongqi.common.senpec.base.utils.ObjectsUtil;
import org.hongqi.common.senpec.base.utils.SymbolSwitcher;
import org.hongqi.common.senpec.file.easyExcel.EasyExcelService;
import org.hongqi.common.senpec.file.fileInfo.FileInfoService;
import org.hongqi.common.senpec.person.certification.batch.CertificationBatch;
import org.hongqi.common.senpec.person.certification.batch.CertificationBatchListener;
import org.hongqi.common.senpec.sys.user.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
@RequiredArgsConstructor
public class CertificationServiceImpl extends IBaseServiceImpl<CertificationMapper, Certification> implements CertificationService {
    private final CertificationMapper certificationMapper;
    private final UserService userService;
    private final FileInfoService fileInfoService;
    private final EasyExcelService<CertificationBatch> easyExcelService;
    private final CertificationBatchListener certificationBatchListener;

    @Override
    public Result<Certification> mySave(Certification entity) {
        entity.setAttachmentUuid(UUID.randomUUID().toString());
        certificationMapper.insert(entity);
        return Result.ok(myGetObjById(entity.getId()));
    }

    @Override
    public Result<?> myRemoveById(Long id) {
        certificationMapper.deleteById(id);
        return Result.ok();
    }

    @Override
    public Result<Certification> myUpdateById(Certification entity) {
        certificationMapper.updateById(entity);
        return Result.ok(myGetObjById(entity.getId()));
    }

    @Override
    public Result<IPage<Certification>> myListObjsWithPage(Certification entity) {
        IPage<Certification> page = new Page<>(entity.getCurrent(), entity.getSize());
        LambdaQueryWrapper<Certification> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ObjectsUtil.noNullAndEmpty(entity.getUserUsername()), Certification::getUserUsername, entity.getUserUsername());
        lambdaQueryWrapper.eq(ObjectsUtil.noNullAndEmpty(entity.getZone()), Certification::getZone, entity.getZone());
        lambdaQueryWrapper.eq(ObjectsUtil.noNullAndEmpty(entity.getMethod()), Certification::getMethod, entity.getMethod());
        lambdaQueryWrapper.eq(ObjectsUtil.noNullAndEmpty(entity.getLevel()), Certification::getLevel, entity.getLevel());
        lambdaQueryWrapper.orderByDesc(Certification::getId);
        IPage<Certification> iPage = certificationMapper.selectPage(page, lambdaQueryWrapper);
        List<Certification> records = iPage.getRecords();
        records.forEach(item -> {
            item.setUserObj(userService.myGetByUsername(item.getUserUsername()));
            item.setAttachmentObj(fileInfoService.getFileInfoByKeyword(item.getAttachmentUuid()));
            item.setIsValid(!(item.getEndDate().isBefore(LocalDate.now())));
            item.setMethodStr(SymbolSwitcher.certificationMethodSwitcher(item.getMethod()));
        });
        iPage.setRecords(records);
        return Result.ok(iPage);
    }

    @Override
    public Result<Certification> myGetById(Long id) {
        return Result.ok(myGetObjById(id));
    }

    @Override
    public Certification myGetObjById(Long id) {
        Certification certification = certificationMapper.selectById(id);
        certification.setUserObj(userService.myGetByUsername(certification.getUserUsername()));
        certification.setCreatorObj(userService.getById(certification.getCreator()));
        certification.setUpdaterObj(userService.getById(certification.getUpdater()));
        certification.setAttachmentObj(fileInfoService.getFileInfoByKeyword(certification.getAttachmentUuid()));
        certification.setIsValid(!(certification.getEndDate().isBefore(LocalDate.now())));
        certification.setMethodStr(SymbolSwitcher.certificationMethodSwitcher(certification.getMethod()));
        certification.setAttachmentObj(fileInfoService.selectByKeyword(certification.getAttachmentUuid()));
        return certification;
    }

    @Override
    public void myExportObjs(HttpServletResponse response) {
        List<Certification> certifications = certificationMapper.selectList(null);
        List<CertificationBatch> certificationBatches = new ArrayList<>();
        for (Certification certification : certifications) {
            CertificationBatch certificationBatch = new CertificationBatch();
            BeanUtils.copyProperties(certification, certificationBatch);
            certificationBatches.add(certificationBatch);
        }
        certificationBatches.forEach(item -> {
            item.setUserName(userService.myGetByUsername(item.getUserUsername()).getName());
            item.setUserJobNo(userService.myGetByUsername(item.getUserUsername()).getJobno());
            item.setMethodStr(SymbolSwitcher.certificationMethodSwitcher(item.getMethod()));
        });
        easyExcelService.exportData(response, CertificationBatch.class, certificationBatches, "证书清单");
    }

    @Override
    public void myImportObjs(Long creator, MultipartFile file) {
        log.info("myImportObjs in certification is running with user {}", creator);
        try {
            EasyExcel.read(file.getInputStream(), CertificationBatch.class, certificationBatchListener).sheet().doRead();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Scheduled(cron = "0 45 9 * * ?")
    public void updateIsValid() {
        log.info("执行更新证书有效性操作。");
        List<Certification> certifications = certificationMapper.selectList(null);
        certifications.forEach(item -> {
            if (item.getEndDate().isBefore(LocalDate.now())) {
                item.setIsValid(false);
                certificationMapper.updateById(item);
            } else {
                item.setIsValid(true);
                certificationMapper.updateById(item);
            }
        });
    }


}
